//
//  DFSongPlayer.m
//  doubanFun
//
//  Created by bing on 16/3/25.
//  Copyright © 2016年 bing. All rights reserved.
//

#import "DFSong.h"
#import "DFSongPlayer.h"

@interface DFSongPlayer ()
@property (nonatomic, strong) DFSong *song;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerItem *playerItem;
@property (nonatomic, strong) NSDateFormatter *dateFormatter;
@property (nonatomic, strong) id playbackTimeObserver;
@property (nonatomic, assign) NSTimeInterval totleSecond;
@property (nonatomic, assign) NSTimeInterval currentSecond;
@property (nonatomic, assign) PALYER_ACTION_STATUS actionstatus;
@end

@implementation DFSongPlayer

+ (instancetype)sharedplayer {
    static DFSongPlayer *player;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        player = [[DFSongPlayer alloc] init];
        player.player = [[AVPlayer alloc] init];
        player.actionstatus = PALYER_ACTION_STATUS_STOP;
        
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setCategory:AVAudioSessionCategoryPlayback error:NULL];
        [session setActive:YES error:NULL];
        
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    });
    return player;
}

- (void)setupSongModal:(DFSong *)song {
    
    if (_song && [_song.sid isEqualToString:song.sid])
    {
        NSLog(@"当前音乐正在播放");
    }
    else
    {
        NSLog(@"创建播放对象");
        [self removeNotification];
        _playerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:song.url]];
        [self.player replaceCurrentItemWithPlayerItem:_playerItem];
        [self setupNotification];
    }
    
    _song = song;
}


#pragma mark - monitoringPlayer

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    AVPlayerItem *playerItem = (AVPlayerItem *)object;
    // 缓存完成,可以开始播放
    if ([keyPath isEqualToString:@"status"])
    {
        if (playerItem.status == AVPlayerStatusReadyToPlay)
        {
            CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;
            
            // 监听播放状态
            [self monitoringPlayback:self.playerItem totalSecond:totalSecond];
        }
        else if (playerItem.status == AVPlayerStatusFailed)
        {
            NSLog(@"缓存失败");
        }
    }
    // 缓存进度
    else if ([keyPath isEqualToString:@"loadedTimeRanges"])
    {
//        NSLog(@"缓存中...");
        if ([self.delegate respondsToSelector:@selector(player:song:loadedProgress:)]) {
            NSTimeInterval timeInterval = [self availableDuration];
            CGFloat totalDuration = CMTimeGetSeconds(self.playerItem.duration);
            CGFloat progress = timeInterval / totalDuration;
            [self.delegate player:self song:_song loadedProgress:progress];
        }
    }
}

// 播放进度
- (void)monitoringPlayback:(AVPlayerItem *)playerItem totalSecond:(CGFloat)totalSecond {
    
    WEAKSELF
    self.playbackTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
        NSTimeInterval totalSecond = CMTimeGetSeconds(playerItem.duration);
        NSTimeInterval currentSecond = CMTimeGetSeconds(playerItem.currentTime);
        if ([weak_self.delegate respondsToSelector:@selector(player:song:currentTime:totalTime:)]) {
            [weak_self.delegate player:weak_self song:weak_self.song currentTime:currentSecond totalTime:totalSecond];
        }
    }];
}

// 播放结束
- (void)itemPlayDidEnd:(NSNotification *)notification {
    WEAKSELF
    [self.player seekToTime:kCMTimeZero completionHandler:^(BOOL finished) {
        if ([weak_self.delegate respondsToSelector:@selector(player:endSong:)]) {
            [weak_self.delegate player:weak_self endSong:weak_self.song];
        }
    }];
}


#pragma mark - action

- (void)play {
    self.actionstatus = PALYER_ACTION_STATUS_PLAY;
    [self.player play];
}

- (void)pause {
    self.actionstatus = PALYER_ACTION_STATUS_STOP;
    [self.player pause];
}

- (void)stop {
    self.player.rate = 0.0;
}

- (PALYER_ACTION_STATUS)status {
    return self.actionstatus;
}


#pragma mark - backgroudTask

- (void)backgroudTask {
    UIImage *image = self.song.albumPicture;
    if (!image) {
        image = [UIImage new];
    }
    MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage:image];
    NSDictionary *songinfo = @{
                               MPMediaItemPropertyTitle: self.song.title,
                               MPMediaItemPropertyArtist: self.song.artist,
                               MPMediaItemPropertyAlbumTitle: self.song.albumtitle,
                               MPMediaItemPropertyArtwork: albumArt,
                               MPMediaItemPropertyPlaybackDuration: @(self.totleSecond),
                               MPNowPlayingInfoPropertyElapsedPlaybackTime:@(self.currentSecond)
                           };
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songinfo];
}


#pragma mark - private
// 计算缓冲进度
- (NSTimeInterval)availableDuration {
    NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges];
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
    float startSeconds = CMTimeGetSeconds(timeRange.start);
    float durationSeconds = CMTimeGetSeconds(timeRange.duration);
    NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度
    return result;
}

// 将秒转化为具体时间
- (NSString *)convertTime:(CGFloat)second {
    NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];
    if (second/3600 >= 1) {
        [[self dateFormatter] setDateFormat:@"HH:mm:ss"];
    } else {
        [[self dateFormatter] setDateFormat:@"mm:ss"];
    }
    NSString *showtimeNew = [[self dateFormatter] stringFromDate:d];
    return showtimeNew;
}

- (NSDateFormatter *)dateFormatter {
    if (!_dateFormatter) {
        _dateFormatter = [[NSDateFormatter alloc] init];
    }
    return _dateFormatter;
}


#pragma mark - notification

- (void)setupNotification {
    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemPlayDidEnd:)
                                                 name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

- (void)removeNotification {
    [self.playerItem removeObserver:self forKeyPath:@"status" context:nil];
    [self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges" context:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.playerItem];
    [self.player removeTimeObserver:self.playbackTimeObserver];
}

- (void)dealloc {
    [self removeNotification];
    NSLog(@"%s",__func__);
}

@end
